
#include <cassert>
#include <cstdlib>

#include <DXGI.h>
#include <D3D10_1.h>
#include <D3DX11.h>

#include "Core\IndexBuffer.h"


IndexBuffer::IndexBuffer(LPVOID data, UINT count)
	: m_data(NULL),
	  m_count(count),
	  m_buffer(NULL),
	  m_binded(FALSE)
{
	m_data = new UINT[count];
	assert(m_data);

	memcpy(m_data, data, sizeof(UINT) * count);
}


IndexBuffer::~IndexBuffer()
{
	// Unbind if needed.
	if(m_binded)
		Unbind();

	// Free system data.
	if(m_data)
	{
		delete[] m_data;
		m_data = NULL;
	}
}


BOOL IndexBuffer::IsBinded() CONST
{
	return m_binded;
}


BOOL IndexBuffer::Bind()
{
	assert(!m_binded);

	// Initialize index buffer description.
	D3D11_BUFFER_DESC description;

	description.Usage = D3D11_USAGE_DEFAULT;
	description.ByteWidth = sizeof(UINT) * m_count;
	description.BindFlags = D3D11_BIND_INDEX_BUFFER;
	description.CPUAccessFlags = 0;
	description.MiscFlags = 0;
	description.StructureByteStride = 0;

	// Initialize index buffer subresource.
	D3D11_SUBRESOURCE_DATA data;

	data.pSysMem = m_data;
	data.SysMemPitch = 0;
	data.SysMemSlicePitch = 0;

	// Create index buffer.
	HRESULT result = GetDevice()->CreateBuffer(&description, &data, &m_buffer);
	assert(SUCCEEDED(result));

	// Change state to binded.
	m_binded = TRUE;

	return m_binded;
}


VOID IndexBuffer::Unbind()
{
	assert(m_binded);

	// Unbind.
	m_buffer->Release();
	m_buffer = NULL;

	// Change state to unbinded.
	m_binded = FALSE;
}


VOID IndexBuffer::Enable()
{
	assert(m_binded);

	// Set index buffer as input of assembler.
	GetContext()->IASetIndexBuffer(m_buffer, DXGI_FORMAT_R32_UINT, 0);
}


UINT IndexBuffer::Size() CONST
{
	return m_count;
}

